﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;

namespace TinySkill
{

    public class SkillSearchWindow : EditorWindow
    {

        [MenuItem("Window/SkillAssetSearchEditor")]

        public static void ShowWindow()
        {
            EditorWindow.GetWindow(typeof(SkillSearchWindow));
        }

        string name = "";
        bool vagueSearch = true;
        List<int> result = new List<int>();
        Regex r;
        string tip = "";
        bool rep;
        string replaceStr = "";
        void OnGUI()
        {
            if (Data.Skill == null)
            {
                EditorGUILayout.LabelField("先打开技能编辑器窗口");
            }
            EditorGUILayout.LabelField(tip);
            name = EditorGUILayout.TextField("资源名称", name);

            vagueSearch = EditorGUILayout.Toggle("正则表达式", vagueSearch);

            rep = EditorGUILayout.Toggle("替换", rep);
            if (rep)
            {
                replaceStr = EditorGUILayout.TextField("替换名称", replaceStr);
            }

            if (GUILayout.Button("搜索"))
            {
                result.Clear();
                if (vagueSearch)
                {
                    try
                    {
                        r = new Regex(name, RegexOptions.IgnoreCase);
                    }
                    catch (Exception e)
                    {
                        tip = "无效的正则表达式";
                    }

                }
                else
                    r = null;
                if (Data.Skill != null)
                {
                    foreach (var s in Data.Skill.Values)
                    {
                        if (Search(s))
                            result.Add(s.id);
                    }
                }
            }

            if (result.Count > 0)
            {
                string content = "查询结果:";

                for (int i = 0; i < result.Count; i++)
                {
                    content += result[i] + "\n";
                }

                GUILayout.TextArea(content);
            }
        }

        bool Search(object o)
        {
            if (o == null)
                return false;

            Type type = o.GetType();
            FieldInfo[] fields = type.GetFields();
            for (int fieldIndex = 0; fieldIndex < fields.Length; fieldIndex++)
            {
                var f = fields[fieldIndex];
                if (f.FieldType == typeof(string))
                {
                    string vStr = (string)f.GetValue(o);

                    if (!string.IsNullOrEmpty(vStr))
                    {
                        //Debug.Log(vStr);

                        if (r != null)
                        {
                            if (r.Match(vStr).Success)
                            {
                                if (rep)
                                {
                                    f.SetValue(o, replaceStr);
                                }
                                return true;
                            }

                        }
                        else if (vStr == name)
                        {
                            if (rep)
                            {
                                f.SetValue(o, replaceStr);
                            }
                            return true;
                        }

                    }

                }
                else if (f.FieldType.IsArray)
                {
                    Array ay = (Array)f.GetValue(o);
                    if (ay != null)
                    {
                        for (int i = 0; i < ay.Length; i++)
                        {
                            if (Search(ay.GetValue(i)))
                                return true;
                        }
                    }
                }
                else if (f.FieldType.IsPrimitive || f.FieldType.IsEnum)
                {
                    continue;
                }
                else if (f.FieldType.IsClass || f.FieldType.IsValueType)
                {
                    if (Search(f.GetValue(o)))
                        return true;
                }

            }

            return false;
        }
    }
}